package com.geneqiao.jdbc.jpa;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

public class ReflectJPA
{
	// 日志
	private static final Logger logger = Logger.getLogger(ReflectJPA.class);

	public static <T> TableStruct getTable(T t)
	{
		String tableName = null;
		// 仅获取自身的注解
		Annotation[] annotations = t.getClass().getDeclaredAnnotations();
		for (Annotation annotation : annotations)
		{
			if (annotation instanceof Table)
			{
				tableName = ((Table) annotation).name();
				break;
			}
		}
		if(tableName != null)
		{
			TableStruct table = new TableStruct(tableName);
			table.setGenerateKey(getGenerageColumn(t));
			table.setPrimaryKey(getPKColumn(t));
			table.setColumns(getColumn(t));
			return table;
		}
		return null;
	}

	static <T> Map<String, Object> getColumn(T t)
	{
		try
		{
			Method[] methods = t.getClass().getDeclaredMethods();
			Map<String, Object> columns = new HashMap<String, Object>();
			for (Method method : methods)
			{
				Annotation[] annotations = method.getAnnotations();
				for (Annotation annotation : annotations)
				{
					if (annotation instanceof Column)
					{
						columns.put(((Column) annotation).name(), getValue(method, t));
						break;
					}
				}
			}
			return columns;
		}
		catch (Exception e)
		{
			logger.error("获取所有的表字段失败", e);
			return null;
		}

	}

	private static <T> Object getValue(Method method, T t)
	{
		Object obj = null;
		try
		{
			if (method.getName().contains("get"))
			{
				obj = method.invoke(t);
				if (obj != null && !"".equals(obj) && !"null".equals(obj))
				{
					return obj;
				}
			}
		}
		catch (IllegalAccessException e)
		{
			logger.error("调用函数失败 => " + method.getName(), e);
		}
		catch (IllegalArgumentException e)
		{
			logger.error("调用函数失败 => " + method.getName(), e);
		}
		catch (InvocationTargetException e)
		{
			logger.error("调用函数失败 => " + method.getName(), e);
		}
		return obj;
	}

	static <T> String getPKColumn(T t)
	{
		Method[] methods = t.getClass().getDeclaredMethods();
		String pkColumn = null;
		for (Method method : methods)
		{
			Annotation[] annotations = method.getAnnotations();
			for (Annotation annotation : annotations)
			{
				//如果自动增长,则为主键
				if (annotation instanceof Id)
				{
					pkColumn = getPKColumnName(annotations);
					break;
				}
			}
		}
		return pkColumn;
	}
	
	static <T> String getGenerageColumn(T t)
	{
		Method[] methods = t.getClass().getDeclaredMethods();
		String pkColumn = null;
		for (Method method : methods)
		{
			Annotation[] annotations = method.getAnnotations();
			for (Annotation annotation : annotations)
			{
				//如果自动增长,则为主键
				if (annotation instanceof GeneratedValue)
				{
					pkColumn = getGenerageColumnName(annotations);
					break;
				}
			}
		}
		return pkColumn;
	}

	private static String getPKColumnName(Annotation[] annotations)
	{
		if (annotations == null)
		{
			return null;
		}
		for (Annotation annotation : annotations)
		{
			if (annotation instanceof Column)
			{
				return ((Column) annotation).name();
			}
		}
		return null;
	}
	
	private static String getGenerageColumnName(Annotation[] annotations)
	{
		if (annotations == null)
		{
			return null;
		}
		for (Annotation annotation : annotations)
		{
			if (annotation instanceof Column)
			{
				return ((Column) annotation).name();
			}
		}
		return null;
	}
}
